package com.dx.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.dx.pojo.LogInfo;
import com.dx.pojo.Task;
import com.dx.service.LogService;
import com.dx.service.MailService;
import com.dx.service.TaskService;
import com.dx.utils.DateUtil;
import com.dx.utils.ParamUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @program: Isp_Automatic_punch
 * @description:
 * @author: hanabi
 * @create: 2022-02-09 22:00
 **/

@RestController
@Slf4j
public class TaskController {
    @Autowired
    private TaskService taskService;

    @Autowired
    private LogService logService;

    @Autowired
    private MailService mailService;

    @Autowired
    private ThreadPoolTaskExecutor executor;

    @PostMapping("/tsk")
    public String addTask(Task task) {
        if (!ParamUtil.paramCheck(task)) {
            return "学号、密码、地区等任何字段不能为空！";
        }
        StringBuilder sb = new StringBuilder();
        synchronized (this) {
            task.setFailedCount(0);
            try {
                if (ObjectUtils.isEmpty(taskService.selectByUsername(task))) {
                    taskService.add(task);
                    sb.append("添加成功！正在打卡...结果稍后通过邮件通知您");
                    log.info("用户{}添加成功！", ObjectUtils.nullSafeToString(task));
                } else {
                    taskService.updateByUsername(task);
                    sb.append("信息更新成功！补偿次数已重置，正在重新打卡...结果稍后通过邮件通知您");
                    log.info("用户{}更新信息成功！", ObjectUtils.nullSafeToString(task));
                }
                executor.execute(() -> {
                    try {
                        taskService.processTask(task);
                    } catch (IOException e) {
                        e.printStackTrace();
                        log.error("任务添加/更新时，打卡操作失败");
                    }
                });
            } catch (Exception e) {
                log.info("用户{}添加异常", ObjectUtils.nullSafeToString(task));
                e.printStackTrace();
                sb.append("信息添加失败！请检查信息是否合法并重试...");
            }
        }
        return sb.toString();
    }

    @GetMapping("/tsk")
    public List<Map<String, String>> getTask() {
        List<Task> taskList = taskService.selectAll();
        List<Map<String, String>> dataList = taskList.stream().map(task -> {
            Map<String, String> map = new LinkedHashMap<>();
            map.put("学号", task.getUsername());
            map.putIfAbsent("邮箱", task.getEmail());
            map.putIfAbsent("地区", task.getAddr());
            map.putIfAbsent("是否已打卡", task.getIsSuc() == 1 ? "是" : "否");
            map.putIfAbsent("打卡失败次数", task.getFailedCount() + "次");
            return map;
        }).collect(Collectors.toList());
        return dataList;
    }

    @GetMapping("/tsk/all")
    public synchronized String processAllTasks() {
        taskService.punchInOneClick();
        return "一键打卡操作成功...";
    }

    @GetMapping("/tsk/reset")
    public String resetAllTasks() {
        taskService.resetAll();
        return "重置操作成功...";
    }

    @GetMapping("/tsk/logs")
    public List<Map<String, String>> getLogs() {
        log.info("==>正在获取所有日志...");
        List<Map<String, String>> mapList = null;
        try {
            LambdaQueryWrapper<LogInfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.orderByDesc(LogInfo::getDate);
            wrapper.last("limit 0,20");
            mapList = logService.list(wrapper).stream().map(info -> {
                Map<String, String> map = new LinkedHashMap<>();
                map.putIfAbsent("时间", DateUtil.getYYMMddHHmmssDate(info.getDate()));
                map.putIfAbsent("接收邮箱", info.getEmail());
                map.putIfAbsent("邮件内容", info.getInfo().replaceAll("\n", "---"));
                return map;
            }).collect(Collectors.toList());
        } catch (Exception e) {
            e.printStackTrace();
            log.info("==>获取日志出错");
        }
        return mapList;
    }

    //        @GetMapping("/msg")
    public void sendMsg() {
        executor.execute(() -> {
            String content = "1.最近大多数新老生已经开学，也收到许多同学的取消打卡的邮件，因此从今天开始将清空所有账号信息，取消所有打卡任务不再自动打卡。\n2.考虑到可能有部分未返校还要打卡的同学，ISP自动打卡服务仍然会运行一段时间。有需要的重新提交一下账号信息就行。地址：http://meetyouat.icu:8080 \n";
            List<String> list = taskService.selectAll().stream().filter(task -> StringUtils.hasLength(task.getEmail())).map(task -> task.getEmail()).collect(Collectors.toList());
            list.stream().forEach(to -> {
                try {
                    mailService.sendMail(to, "ISP自动打卡脚本公告", content);
                    Thread.sleep(1000 * 30);
                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("ISP打卡脚本公告发送失败! 账号==>" + to);
                }
            });
        });
    }

    @GetMapping("/tsk/remove/{id}")
    public String remove(@PathVariable("id") String id) {
        boolean isSuccess;
        log.error("正在通过学号删除任务==>" + id);
        try {
            isSuccess = taskService.removeByUsername(id);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("通过学号删除任务失败==>" + id);
            return "学号==>" + id + "打卡任务删除失败";
        }
        if (!isSuccess) {
            log.error("通过学号删除任务失败==>" + id);
            return "学号==>" + id + "打卡任务删除失败";
        }
        log.error("通过学号删除任务成功==>" + id);
        return "学号==>" + id + "打卡任务删除成功";
    }
}
